/**
 * libnlog -- User friendly logging system with network support.
 *
 * Copyright (C) 2011
 * 	Samuel Nussbaum <samuel (dot) nussbaum (at) e-robot.ch>
 *
 * This library is free software; you can redistribute it and/or modify it under the terms of the
 * GNU Lesser General Public License as published by the Free Software Foundation; either version 3
 * of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this
 * library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 */
#ifndef __NLOG_LOGGER_H__
#define __NLOG_LOGGER_H__

#include "Types.hpp"
#include "Message.hpp"
#include "Stream.hpp"

#include <set>

namespace nlog {

class Logger
{
	public:
		struct Destroyer {
			virtual ~Destroyer();
		};

		struct Hash: public std::unary_function<Logger *, std::size_t> {
			SizeT operator()(const Logger *_value) const { return _value->m_hashName; }
		};

		struct Equal: public std::binary_function<Logger *, Logger *, bool> {
			bool operator()(const Logger *_a, const Logger *_b) const {
				return _a->hash() == _b->hash();
			}
		};

		typedef ::std::allocator<Logger *> Allocator;
		typedef ::boost::unordered_set<Logger *, Hash, Equal, Allocator> LoggerSet;
		typedef ::std::set<Message, Message::Less> MessageSet;

		Logger(const Logger &);
		virtual ~Logger();
		virtual void write(const Message &) const;
		Logger &operator=(const Logger &);
		Stream finest();
		Stream finer();
		Stream fine();
		Stream info();
		Stream config();
		Stream warning();
		Stream error();
		SizeT hash() const;
		String name() const;
		LevelEnum level() const;
		void setLevel(LevelEnum);
		static Logger &instance(const String &);

	protected:
		Logger(const String &_name);
		static void run();
		LevelEnum m_level;
		SizeT m_hashName;
		String m_name;
		OStream *m_stream;
		static Thread *m_thread;
		static Mutex *m_mutex;
		static LoggerSet *m_instances;
		static MessageSet m_buffer;
		static const String m_kNames[];
		static const String m_kColors[];
};



}

#endif /* __NLOG_LOGGER_H__ */
